package com.wn.pianTai.controller;


import com.wn.pianTai.utils.CookieUtils;
import com.wn.serviceLa.util.JwtUtils;
import com.wn.serviceLa.util.Md5Util;
import com.google.code.kaptcha.Producer;
import com.wn.dal.entity.User;
import com.wn.serviceLa.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wnlqy
 * @since 2023-04-26 12:10:21
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    JavaMailSender javaMailSender;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    UserService userService;

    @Autowired
    Producer producer;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @RequestMapping("/requestEmailCode")
    public String requestEmailCode(String email){
        //校验邮箱地址是否合法
        String str="^" +
                "([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)*@" +
                "([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+" +
                "[\\.][A-Za-z]{2,3}" +
                "([\\.][A-Za-z]{2})?" +
                "$";
        Pattern p = Pattern.compile(str);
        Matcher m = p.matcher(email);
        if(!m.matches()){
            return "邮箱地址非法,请正确填写";
        }

        //发送向邮箱发送验证码
        String Code = "3253413";
        stringRedisTemplate.opsForValue().set(email,Code,5L, TimeUnit.MINUTES);
        sendEmail(email,"欢迎光临瑞幸咖啡","您的取货码是 "+Code+" ,有效期5分钟,请尽快使用");

        return "ok";
    }

    private void sendEmail(String email, String subject, String content){
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("3300461359@qq.com");
        message.setTo(email);
        message.setSubject(subject);
        message.setText(content);

        javaMailSender.send(message);
    }

    @RequestMapping("/register")
    public String register(String username, String password, String repass, String email, String emailCode) {
        if (StringUtils.isEmpty(email)) {
            return "地址不能为空";
        }
        String redisEmail = stringRedisTemplate.opsForValue().get(email);
        if (StringUtils.isEmpty(redisEmail)|| StringUtils.isEmpty(repass) || !password.equals(repass)) {
            return "密码错误或两次输入不一致";
        }
        if (StringUtils.isEmpty(redisEmail) || StringUtils.isEmpty(emailCode) || !redisEmail.equals(emailCode)){
            return "邮箱验证码非法";
        }


        synchronized (username.intern()) {  //同步锁,处理相同用户名注册的情况,避免多线程错误
            User userByName = userService.getUserByUsername(username);


            try {
                System.out.println(Thread.currentThread().getName());
                System.out.println("模拟任务阻塞30s");
                TimeUnit.SECONDS.sleep(30);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            if (userByName != null) {
                return "用户名已经被占用";
            }
            //通过校验,写入新用户
            User user = new User();
            user.setAccount(username);
            user.setPassword(Md5Util.encode(password));
            user.setEmail(email);
            user.setCreatetime(new Date());
            user.setUpdatetime(new Date());

            userService.save(user);
        }
        return "ok";
    }

    @RequestMapping("/getKaptchaCode")
    public void getKaptchaCode(HttpServletResponse response , HttpServletRequest request) throws IOException {
        //生成验证码
        String code = producer.createText();

        request.getSession().setAttribute("loginCode",code);

        //生成验证码图片
        BufferedImage image = producer.createImage(code);

        response.setContentType("image/png");
        ImageIO.write(image, "jpg", response.getOutputStream());

    }

    @RequestMapping("logout")
    public String logout(HttpServletRequest request, HttpServletResponse response){

        //session方案
//        request.getSession().removeAttribute("currentUser");

        //JWT方案
        CookieUtils.deleteUserTokenFromCookie(response);

        String userTokenFromCookie = CookieUtils.getUserTokenFromCookie(request);
        stringRedisTemplate.delete(userTokenFromCookie);

        return "ok";
    }

    @RequestMapping("/login")
    public String login(String username, String password, String code, HttpServletRequest request, HttpServletResponse response){
        String loginCode = (String)request.getSession().getAttribute("loginCode");
        if (StringUtils.isEmpty(loginCode) || StringUtils.isEmpty(code) || !loginCode.equalsIgnoreCase(code)){
            return "验证码错误,请重试";
        }

        User userByName = userService.getUserByUsername(username);
        if (userByName==null || !userByName.getPassword().equals( Md5Util.encode(password) )){
            return "用户名或密码错误";
        }

        //保存登录状态 session
//        request.getSession().setAttribute("currentUser",userByName.getAccount());

        //jwt方案
        String token = JwtUtils.createToken(userByName.getAccount(), 30);
        CookieUtils.setUserToken2Cookie(response,token);

        //同时保存一份关联数据
        stringRedisTemplate.opsForValue().set(token,userByName.getAccount(),60L, TimeUnit.MINUTES);

        return "ok";
    }

    @RequestMapping("/currentUser")
    public String currentUser(HttpServletRequest request){
        //session方案
//        return (String) request.getSession().getAttribute("currentUser");

        //Jwt方案
        String userTokenFromCookie = CookieUtils.getUserTokenFromCookie(request);
        String userName = JwtUtils.getAccountWithoutException(userTokenFromCookie);
        return userName;
    }

}

